﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Tsanie.ShellExtension;
using System.Drawing;
using System.IO;
using SharpZipLib.Zip;

namespace Tsanie {
    [Guid("C1B474CD-37F6-40C5-90F7-583A4CC83D6D")]
    [ComVisible(true), ExtensionFileTypes(".osz")]
    public class OszThumbnail : ThumbnailHandlerBase {

        #region - Overrides -

        protected override Bitmap GetImage {
            get {
#if DEBUG
                Common.OutputDebugString("get_GetImage(void):: Create start... {0}", this.Filename);
#endif
                Bitmap bmp = null;
                try {
                    bmp = OszThumbnail.GetBackgroundFromOsz(this.Filename);
                } catch (Exception e) {
                    Common.OutputDebugString("get_GetImage(void):: Exception, {0} - {1}", e.GetType().FullName, e.Message);
                }
                return bmp;
            }
        }

        #endregion

        public static Bitmap GetBackgroundFromOsz(string filename) {
            FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            if (stream.Length == 0) {
                Common.OutputDebugString("get_GetImage(void):: Error - file length == 0. {0}", filename);
                stream.Close();
                stream = null;
                return null;
            }
            ZipInputStream zip = new ZipInputStream(stream);
            ZipEntry entry;
            string bgFile = null;
            bool found = false;
            while (!found && ((entry = zip.GetNextEntry()) != null)) {
                int pos = entry.Name.LastIndexOf('.');
                if (pos >= 0) {
                    if (entry.Name.Substring(pos).ToLower() == ".osu") {
                        // 找到.osu文件
                        if (entry.Size <= 0) {
                            Common.OutputDebugString("GetBackgroundFromOsz(Stream):: Warning entry size == 0. {0}", entry.Name);
                            break;
                        }
                        byte[] bs = new byte[entry.Size];
                        zip.Read(bs, 0, bs.Length);
                        StreamReader reader = new StreamReader(new MemoryStream(bs));
                        string line;
                        bool isTaiko = false;
                        while ((line = reader.ReadLine()) != null) {
                            if (!isTaiko && line.StartsWith("Mode:")) {
                                isTaiko = (line.Substring(5).Trim() == "1");
                            } else if (!isTaiko && line.StartsWith("0,0,\"")) {
                                line = line.Substring(5).Trim(new char[] { ' ', '\"' }).ToLower();
                                if (line.EndsWith(".jpg") || line.EndsWith(".png")) {
                                    // 找到图片
                                    bgFile = line;
                                    found = true;
                                    break;
                                }
                            }
                        }
                        reader.Close();
                        reader = null;
                        bs = null;
                    }
                }
            }
            zip.Close();
            zip = null;
            stream = null;
            if (!found) {
#if TRACE
                Common.OutputDebugString("GetBackgroundFromOsz(Stream):: Warning '{0}' hasn't a bgFile.", filename);
#endif
                return null;
            }
            zip = new ZipInputStream(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
            Bitmap bmp = null;
            while ((entry = zip.GetNextEntry()) != null) {
                if (entry.Name.Substring(entry.Name.LastIndexOf('/') + 1).ToLower() == bgFile) {
                    // 找到背景图片
                    if (entry.Size <= 0) {
                        Common.OutputDebugString("GetBackgroundFromOsz(Stream).GetImage:: Warning entry size == 0. {0}", entry.Name);
                        break;
                    }
                    byte[] bs = new byte[entry.Size];
                    zip.Read(bs, 0, bs.Length);
                    try {
                        bmp = Bitmap.FromStream(new MemoryStream(bs)) as Bitmap;
                    } catch (Exception e) {
                        Common.OutputDebugString("GetBackgroundFromOsz(Stream).GetImage:: Exception, {0} - {1}", e.GetType().FullName, e.Message);
                    }
                    bs = null;
                }
            }
            zip.Close();
            zip = null;
            return bmp;
        }

    }
}
